# -*- coding: utf-8 -*-
"""
Created on Wed Aug 14 09:16:45 2019

@author: admin

每过一条规则，就修改一次data，简称迭代修改
"""
import datetime
import market_label_rule
import time
import json
import re
import pandas as pd

#判断多包项目并返回关键值
def bag_judge(name):
    if name in ['-1','-2']:
        return False
    pattern = '(包|组|标|段|目)[0-9A-Za-z一二三四五六七八九]+[)）]*$|[（(]*[-]*[0-9A-Za-z一二三四五六七八九]+[期包]*[)）]*$'
    pattern_key = '[0-9A-Za-z一二三四五六七八九]'
    flag = re.search(pattern, name)
    if flag:
        match = flag.group(0)
        if len(match) <= 4:
            flag_key = re.search(pattern_key, match)
            if flag_key:
                return True
    return False      

#判断单条规则里的单个规则                
def rule_judge_single(data, rule, id_text_match):
    for k, v in rule.items():
        k = k.split('|')
        name_split = k[0].split('.')
        if len(name_split) == 1:
            data_temp = data[name_split[0]]
        else:
            data_temp = data[name_split[0]][0][name_split[1]]
        if k[0] == 'notice.notice_id':
            v_copy = v
            v = [data_temp]
            data_temp = id_text_match['|'.join(v_copy)]
        if k[1] == '包含':
            if any(vv in data_temp for vv in v):
                return True
            else:
                return False
        elif k[1] == '包含所有':
            if all(vv in data_temp for vv in v):
                return True
            else:
                return False
        elif k[1] == '不包含':
            if all(vv not in data_temp for vv in v):
                return True
            else:
                return False
        elif k[1] == '不包含所有':
            if all(vv in data_temp for vv in v):
                return False
            else:
                return True
        elif k[1] == '大于':
            if float(data_temp) > float(v[0]):
                return True
            else:
                return False
        elif k[1] == '大于等于':
            if float(data_temp) >= float(v[0]):
                return True
            else:
                return False
        elif k[1] == '小于':
            if float(data_temp) < float(v[0]):
                return True
            else:
                return False
        elif k[1] == '小于等于':
            if float(data_temp) <= float(v[0]):
                return True
            else:
                return False
        elif k[1] == '等于':
            if float(data_temp) == float(v[0]):
                return True
            else:
                return False
        elif k[1] == '不等于':
            if float(data_temp) != float(v[0]):
                return True
            else:
                return False

#判断规则列表里的单条规则并打标           
def rule_judge(data, rule, id_text_match):
    for key, value in rule.items():
        #标签
        label = key
        #实体
        entity = value[1]
        for v in value[0]:
            result = rule_judge_single(data, v, id_text_match)
            if not result:
                return data
    #当所有规则都符合时
    if entity == 'tags':
        if label not in data[entity]:
            data[entity].append(label)                      
    else:
        if label not in data[entity][0]['tags']:
            if data[entity][0]['name'] not in ['-1','-2']:
                data[entity][0]['tags'].append(label)  
    return data

#判断规则列表
def return_label(data, rule_list, id_text_match):
    #重置所有标签
    data['tags'] = []                     
    data['customer'][0]['tags'] = []
    data['supplier'][0]['tags'] = [] 
    #以迭代的方式获取body
    for rule in rule_list:
        data = rule_judge(data, rule, id_text_match)
    #补充人工标签
    if data.keys().__contains__('tags_artificial'):
        for tag_artificial in data['tags_artificial']:
            if not tag_artificial:
                continue
            if tag_artificial not in data['tags']:
                data['tags'].append(tag_artificial)
    #补充多包标签
    is_bag = bag_judge(data['prj_name'])
    if is_bag:
        data['is_bag'] = True
    else:
        data['is_bag'] = False
    timenow = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    data['last_update_time'] = timenow
    return data

#使用嵌套聚合搜索标签不一致的实体
def label_unite(_es,es_index,doc_type,entity):
    start = time.time()
    body = {
      "size": 0,
      "query": {
        "term": {
          "is_delete": False
        }
      }, 
      "aggs": {
        "comm_aggs": {
          "nested": {
            "path": entity
          },
          "aggs": {
            "class_entity": {
              "terms": {
                "field": entity+".name",
                "size": 2147483647
              },
              "aggs": {
                "class_tag": {
                  "terms": {
                    "field": entity+".tags",
                    "size": 300
                  }
                }
              }
            }
          }
        }
      }
    }    
    list_modify = []
    search_result = _es.search(index=es_index,doc_type=doc_type,body=body)
    buckets = search_result["aggregations"]["comm_aggs"]["class_entity"]['buckets']
    for bucket in buckets:
        #统计重名实体个数
        doc_count = bucket['doc_count']
        if doc_count > 1:        
            for b in bucket['class_tag']['buckets']:
                #标签个数与实体个数不一致时，则证明标签未统一
                if b['doc_count'] != doc_count:
                    key = bucket['key']
                    list_tag = []
                    #返回实体名称及其对应的所有标签
                    for t in bucket['class_tag']['buckets']:
                        list_tag.append(t['key'])
                    list_modify.append([key,list_tag])               
                    break
        else:
            break
    end = time.time()
    print('定位%s实体耗费时间%s' % (entity,str(end-start)))
    return list_modify

#修改实体标签使其统一
def label_modify(_es,es_index,doc_type,list_modify,entity,scroll='5s',size=100):
    start = time.time()
    for modify in list_modify:
        list_bulk = []
        name = modify[0]
        body = {                
          "query": {
            "bool": {
              "must": [
                {
                  "nested": {
                    "path": entity,
                    "query": {
                      "term": {
                        entity+'.name':name
                      }
                    }
                  }
                },
                {
                  "term": {
                    "is_delete": False
                  }
                }
              ]
            }
          }
        }
        search_result = _es.search(index=es_index, doc_type=doc_type, scroll=scroll, body=body, size=size)
        page = ['1']
        while(len(page) > 0):    
            page = search_result['hits']['hits']
            for p in page:
                p = p['_source']
                p[entity][0]['tags'] = modify[1]
                    
                list_bulk.append({'update':{'_index':es_index, '_type':doc_type, '_id':p['id']}})
                list_bulk.append({'doc':p})
            if len(list_bulk) == 200:
                _es.bulk(index=es_index, doc_type=doc_type, body=list_bulk)
                list_bulk = []
            sid = search_result['_scroll_id']
            search_result = _es.scroll(scroll_id=sid, scroll=scroll)            
        if list_bulk:
           _es.bulk(index=es_index, doc_type=doc_type, body=list_bulk)
    end = time.time()
    print('修改%s实体耗费时间%s' % (entity,str(end-start)))
    return None

if __name__ == '__main__':     
    data = {'bid_price': 5000000, 
            'budget': 5000000, 
            'buy_type': '公开招标', 
            'competitor': [], 
            'create_time': 1571726879776, 
            'customer': [{'comp_name': '广州市规划和自然资源局黄埔区分局', 'name': '广州市规划和自然资源局黄埔区分局', 'tags': ['政务']}], 
            'deal_time': '2019-10-18', 
            'delete_reason': '', 
            'id': 251095, 
            'is_delete': False, 
            'last_update_time': 1571726879776, 
            'need_review': False, 
            'prj_id': 'GZCQC1900FG09005-1', 
            'prj_name': '广州市黄埔区长洲岛地区规划师咨询服务项目2', 
            'publish_time': '1970-01-01', 
            'status': '中标', 
            'supplier': [{'area': 'null', 'city': '广州市', 'comp_name': '广州市城市规划勘测设计研究院', 'name': '广州市城市规划勘测设计研究院', 'province': '广东省', 'tags': ['合作伙伴', '政务', 'DICT厂家']}], 
            'tags': ['信息化咨询设计', '非信息化咨询设计', '大单', '政务', '广通服关注项目']
            }
    data = {
          "tags_artificial": [],
          "buy_type": "竞争性磋商",
          "create_time": "2019-11-04 23:16:32",
          "prj_id": "SZCYLZX2019-W-C-017号",
          "deal_time": "2019-08-01",
          "is_delete": False,
          "tags": [
            "DICT",
            "政务",
            "广通服关注项目"
          ],
          "delete_reason": [],
          "last_update_time": "2019-12-13 08:51:12",
          "review_date": "2019-12-13 08:51:12",
          "need_review": False,
          "split": False,
          "competitor": [],
          "publish_time": "2019-08-01",
          "supplier": [
            {
              "area": "吴中区",
              "province": "江苏省",
              "city": "苏州市",
              "comp_name": "苏州市良丰建设工程有限公司",
              "name": "苏州市良丰建设工程有限公司",
              "tags": [
                "政务",
                "其他1",
                "其他2"
              ]
            }
          ],
          "id": 258354,
          "prj_name": "公寓监理苏州市吴中区人民政府横泾街道办事处关于采购新思家园一期、二期充电桩",
          "is_bag": False,
          "bid_price": 2050000,
          "budget": 2050000,
          "customer": [
            {
              "area": "吴中区",
              "comp_short": "吴区政街",
              "province": "江苏省",
              "city": "苏州市",
              "comp_name": "苏州市吴中区人民政府横泾街道办事处",
              "name": "苏州市吴中区人民政府横泾街道办事处",
              "tags": []
            }
          ],
          "notice": [
            {
              "notice_time": "2019-11-04 00:00:00",
              "notice_id": 803188,
              "url": "https://www.bidcenter.com.cn/news-75245511-4.html"
            }
          ],
          "status": "中标"
        }
    
    es_access = 'http://47.112.138.184:9202'
    es_index = 'projecttest1'
    doc_type='_doc'

#    _es = Elasticsearch([es_access], timeout=60, max_retries=3, retry_on_timeout=True)
#    print(es_access+'已连接') 
    

#    list_rule = market_label_rule.rule_get()
#    list_rule_1 = market_label_rule.rule_get()    
#    df = pd.read_excel('项目筛选规则20191120v1.xlsx')
#    for i in range(len(df)):
#        word = df['全文检索关键词'][i]
#        label = df['二级标签'][i]
#        temp = {label: [[{'notice.notice_id|包含': [word]}], 'tags']}
#        list_rule_1.append(temp)
#    dict_text = dict_textmatch_id
#    print(len(list_rule))
#    list_rule, id_text_match = market_label_rule.rule_word_transform()
    print(len(list_rule))
    s = time.time()    
    result = return_label(data, list_rule, id_text_match)
    print(result['tags'])
    print(result['customer'][0]['tags'])
    print(result['supplier'][0]['tags'])                 
    e = time.time()
    print(str(e-s))

    
    